home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
batchut
/
rbsetnv1.zip
/
EVAL.C
< prev
next >
Wrap
Text File
|
1991-01-03
|
6KB
|
177 lines
/*
* eval.c - evaluate a command, with command substitution, environment variable
* substitution, and wildcard expansion
*
* Author: R. Brittain 4/11/90
*
* Popen() is adapted from code obtained from simtel20
* Recommended wildcard expansion code to use with this is wildargv.c by
* Frank Whaley and placed in the public domain
*
* Syntax:
* eval command argument argument .....
*
* Description:
* The arguments to eval are first wildcard expanded (wildcards expanded into
* alphabetically sorted lists as in unix) and then interatively scanned
* for variable substitutions (%val or $val if you prefer) and command
* substitutions (commands enclosed in `....`)
* After the expansion, the first word is taken to be a command, which
* is then executed , with the rest of the expansion as arguments.
*
* Command substitutions are usually performed by loading a shell (%SHELL or
* %COMSPEC) to run the the command. If the first character of the
* command is '@' the command is exec'ed directly (much faster than calling
* system, but only works with .exe and .com files). Loading a shell allows
* internal commands, batch files, shell aliases and pipelines.
*
* The magic characters %,`, and @ are set below by #defines
*
* This code placed in the public domain
*
* If your shell cannot handle a switch character other than /, #define SWITCH
* By default, the subshells will be called as %COMSPEC ?c command - where ?
* is the current switchar. Defining SWITCH forces use of /
*
* Revision history
* 1.0 - first posted to net Dec 90 RB
* 1.01 - fixed argument parsing so `.....` can span multiple arguments
* without needing to be double quoted Jan 91 RB
*
*/
#include <string.h>
#include <ctype.h>
#include <dos.h>
#include <stdlib.h>
#include <stdio.h>
#include <process.h>
#include "comsub.h"
#define MEMCHECK(x) if ((x) == NULL) fatal("Out of memory",1)
/* prototypes */
void fatal(char *msg, int status);
char *concat(char *, char *);
extern int getswitch(void);
extern int setswitch(char);
main(int argc, char **argv)
{
char version[] = "eval version 1.01 of "__DATE__ ;
char usage[] = "Usage: eval command argument argument ...\n";
static char *command_com = "COMMAND.COM";
static char dash_c[ 3 ] = { '?', 'c', '\0' };
int status, i;
char *shell, *bp, *shellpath, *command;
char saveswitch; /* Save the switch char */
estring s = {NULL, NULL, 0, 80} ;
if (argc == 1)
fatal(usage,1);
/* process command line for back-quotes and unexpanded env. vars. */
rebuild_argv(&argc,&argv);
/* now run the command, with the rest of the line as arguments */
if (*argv[1] == EXE) {
/*
* we can spawn directly, and we know argv is now null terminated,
* but first we must test the length of the generated command line
* and truncate it if needed
*/
int totlen=0;
for (i=1; argv[i] != NULL; i++) {
totlen += strlen(argv[i]) + 1;
if (totlen > MAXARGLINE) {
/* we ran over in argv[i] - truncate it and all following args */
*(argv[i] + strlen(argv[i]) - (totlen - MAXARGLINE)) = '\0';
fputs("Warning: command line too long: truncated\n",stderr);
argv[i+1] = (char *)NULL;
break;
}
}
#ifdef DEBUG
fprintf( stderr, "Running: %s", argv[1]+1 );
for (i=2; argv[i] != NULL; i++) fprintf(stderr," %s",argv[i]);
fprintf(stderr,"\n");
#endif DEBUG
status = spawnvp( P_WAIT, argv[1]+1, argv+1);
} else {
/* we need to call a shell */
/* first make the arguments into one long string */
for (i=1; argv[i] != NULL; i++) {
addstring(&s, " ", 1);
addstring(&s, argv[i], strlen(argv[i]));
}
/* Determine the command processor */
if( ((shell = getenv( "SHELL" )) == (char *) NULL) &&
((shell = getenv( "COMSPEC" )) == (char *) NULL) ) shell = command_com;
strupr( shell );
shellpath = shell;
/* Strip off any leading backslash directories */
shell = strrchr( shellpath, '\\' );
if ( shell != (char *) NULL )
++shell;
else
shell = shellpath;
/* Strip off any leading slash directories */
bp = strrchr( shell, '/' );
if ( bp != (char *) NULL )
shell = ++bp;
if ( strstr( shell, "KSH" ) != NULL ) {
/* MKS Shell needs quoted argument */
command = concat("'",s.b);
command = concat(command,"'");
} else {
command = s.b;
}
saveswitch = dash_c[ 0 ] = (char) getswitch();
#ifdef SWITCH
setswitch('/');
dash_c[ 0 ] = '/';
#endif
/* Test the length of the generated command line */
if (strlen(command) + strlen(shell) + 4 > MAXARGLINE) {
fputs("Warning: command line too long: truncated\n",stderr);
*(command + MAXARGLINE -strlen(shell) -strlen(dash_c) -2) = '\0';
}
/* Run the program */
#ifdef DEBUG
fprintf(stderr,"Running: (%s) %s %s %s\n",shellpath,shell,dash_c,command);
#endif DEBUG
status = spawnl( P_WAIT, shellpath, shell, dash_c, command, (char *) NULL );
#ifdef SWITCH
setswitch(saveswitch);
#endif
}
if (status) fprintf(stderr,"eval: %s status %d\n", argv[1], status);
return(status);
}
void fatal(char *msg, int status)
{
fputs(msg,stderr);
exit(status);
}
char *concat(s1, s2)
char *s1, *s2;
{
/*
* return the concatenation of s1 and s2 in malloced memory
*/
char *p;
p = malloc(strlen(s1)+strlen(s2)+2);
if (p == (char *)NULL) {
fatal ("Out of memory\n",1);
} else {
strcpy(p,s1);
strcat(p,s2);
}
return(p);
}